#ifndef _OPERATOR_H_
#define _OPERATOR_H_

#include <vector>
#include <string>

#include "Common.h"
#include "OperatorCost.h"

#define EMPTY_OPERATOR ("_empty")

class Operator
{
private:
	std::string name;

	int properties;
	std::vector <Operator *> opsComm;
public:
	Operator(std::string name);

	std::string getName();

	int getOperatorProperties();
	void setOperatorProperties(int property);
	int checkProperty(int properties);

	void addCommOps(std::vector <Operator *> &opsComm);
	Operator *findCommOp(Operator *op);
};

typedef std::vector<struct OperatorNode *> Dependencies;

struct PhysicalOperator
{
	std::string realizationName;
	Operator *op;
	Cost *cost;

	PhysicalOperator(std::string realizationName, Operator *op, Cost *cost = 0);
	~PhysicalOperator();
};

struct OperatorNode
{
	Operator *op;
	PhysicalOperator *physOp;
	Dependencies *dependencies;
	std::string label;
	//NOTE: Add more properties here.

	// Make sure that after proreties addition 
	// they will be properly handled in the constructors and destructor
	OperatorNode(Operator *op, PhysicalOperator *physOp = 0, Dependencies *dependencies = 0);
	OperatorNode(const OperatorNode &node);
	~OperatorNode();
};

void clearOperators();

Operator *findLogicalOperatorbyName(std::string name);
void findPhysicalOperatorbyName(std::string name, std::vector <PhysicalOperator *> &list);
struct Query *findOperatorNodeinQuery(struct Query *query, OperatorNode *node);
OperatorNode *findOperatorNode(Query *query, std::string label);

#endif
